home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC Media 22
/
PC MEDIA CD22.iso
/
share
/
prog
/
spm220e
/
modem.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1995-09-13
|
9KB
|
247 lines
{
╔═════════════════════════════════════════════════════════════════════════════╗
║ NAME : MODEM.PAS ║
║ FUNCTION : Library to control the used (TeleTex OR HAYES) modem. ║
║ REMARKS : ■ To activate this unit clock interrupt, you have to include the║
║ : following lines in the main routine: ║
║ : GetIntVec($1C,Int1CSave); ║
║ : SetIntVec($1C,Addr(Check_HModem_State)); ║
║ : Do NOT forget to disactivate it before terminating the program: ║
║ : SetIntVec($1C,Int1CSave); ║
║ : This interrupt will up-date the "connected" variable at each ║
║ : second for an HAYES modem. It will also up-date the "C" signal ║
║ : into screen to inform the user that he is connected ("ShowCorF" ║
║ : has to be set TRUE for this...). ║
║ : Please, note that "HayesModemState" and "Check_HModem_State" ║
║ : can't be used to check the connect status of the Minitel: ║
║ : The connect status of it must be interpreted by the VideoTex ║
║ : transcoding procedure... ║
║ COPYRIGHT : HETRU Fabrice 1991-1995. ║
╚═════════════════════════════════════════════════════════════════════════════╝
}
UNIT Modem;
interface
USES Crt,Dos,StarIntf;
TYPE
CmdeStr = STRING[20] ;
CONST
(* Modem type in use: MINITEL ou HAYES ? *)
TlTex = 0 ;
Hayes = 1 ;
(* Command codes to send to the modem. *)
Generique = 0 ;
InitMod = 1 ;
Connect = 2 ;
Appel = 3 ;
Raccroch = 4 ;
ConnexFin = 5 ;
(* Screen RAM Segment. *)
seg_ecran : WORD = $B000 ;
VAR
ModemUsed : SHORTINT ; (* Modem type in use: Hayes/Minitel ? *)
DTR_Cmde : BOOLEAN ; (* Is DTR used as a command prefix ? *)
HAYESPrefix : STRING[3] ; (* Command prefix for the HAYES modem. *)
PulseDial : BOOLEAN ; (* Pulses call ? (or Frequency calls ?). *)
connected : BOOLEAN ; (* Connected status flag. *)
Show_CorF : BOOLEAN ; (* Write (or not) the connect status on screen*)
Int1CSave : POINTER ; (* Back-up for the last interrupt vector... *)
PROCEDURE CmdeToModem(TypCmde: BYTE;DataCmde: CmdeStr);
{ HAYES and TlTex commands maker. }
PROCEDURE HayesModemState; { Up-dates the connect status. }
PROCEDURE Check_HModem_State; INTERRUPT; { Clock interrupt to check the con- }
{ -nect status... }
implementation
TYPE
Vecteur = RECORD
Offset : WORD ;
Segment : WORD ;
END;
CONST
OldIntrp1C : Vecteur = (Offset:0;Segment:0) ;
VAR
reg88 : Registers ;
ItClk_active : BOOLEAN ;
PROCEDURE Beep(Freq, Tempo: WORD);
BEGIN
Sound(Freq);
Delay(Tempo);
NoSound
END;
PROCEDURE CmdeToModem(TypCmde: BYTE;DataCmde: CmdeStr);
VAR
Chaine_CMDE : CmdeStr ;
Sended,
Nb_transmited : WORD ;
BEGIN
Chaine_CMDE := '';
CASE ModemUsed OF
TlTex: BEGIN
CASE TypCmde OF
Generique: Chaine_CMDE := #$1B+#$39+#$67;
InitMod: Chaine_CMDE := '';
Connect: Chaine_CMDE := #$1B+#$39+#$68;
Appel: Chaine_CMDE := '';
Raccroch: Chaine_CMDE := #$1B+#$39+#$67;
ConnexFin: IF connected THEN Chaine_CMDE := #$13+#$49
ELSE Chaine_CMDE := #$1B+#$39+#$68
END;
IF Length(Chaine_CMDE)>0 THEN
IF WriteSerie(Chaine_CMDE[1],Length(Chaine_CMDE),Nb_transmited)<>0
THEN Beep(500,500)
END;
Hayes: BEGIN
CASE TypCmde OF
Generique: Chaine_CMDE := Chaine_CMDE + DataCmde;
InitMod:
IF DTR_Cmde THEN Chaine_CMDE := 'AT Z0 &D1 X0 V2 B2'
ELSE Chaine_CMDE := Chaine_CMDE + 'AT Z0 X0 V2 B2';
Connect: Chaine_CMDE := Chaine_CMDE + 'ATD';
Appel: IF connected OR (DataCmde='') THEN Chaine_CMDE := ''
ELSE
BEGIN
Chaine_CMDE := Chaine_CMDE + 'ATD' ;
IF PulseDIAL THEN Chaine_CMDE := Chaine_CMDE + 'P'
ELSE Chaine_CMDE := Chaine_CMDE + 'T';
Chaine_CMDE := Chaine_CMDE + DataCmde
END;
Raccroch: Chaine_CMDE := Chaine_CMDE + 'ATH0';
ConnexFin: IF connected THEN Chaine_CMDE := Chaine_CMDE + 'ATH0'
ELSE Chaine_CMDE := Chaine_CMDE + 'ATD'
END;
IF Length(Chaine_CMDE)>0 THEN
BEGIN
IF NOT DTR_Cmde THEN
BEGIN
IF connected THEN
BEGIN
Delay(1000);
Sended:=WriteCmde(HAYESPrefix[1],Length(HAYESPrefix),DTR_Cmde);
IF Sended=0 THEN Delay(1000);
END
ELSE Sended := 0;
END
ELSE Sended := 0;
IF Sended=0 THEN
BEGIN
Chaine_CMDE := Chaine_CMDE + #$0D;
IF WriteCmde(Chaine_CMDE[1],Length(Chaine_CMDE),DTR_Cmde)<>0
THEN Beep(500,500);
IF connected THEN
BEGIN
Delay(1200);
Chaine_Cmde := 'ATO' + #$0D;
Sended:=WriteCmde(Chaine_CMDE[1],Length(Chaine_CMDE),FALSE);
END
END;
END
END;
END
END;
PROCEDURE HayesModemState;
VAR
voie : CHAR ;
x : BOOLEAN ;
xx : BYTE ;
BEGIN
IF ModemUsed=Hayes THEN
Etat_du_modem(voie,x,x,x,connected,x,xx,xx,xx,xx)
END;
{$F+}
PROCEDURE Check_HModem_State;
VAR
compteur : BYTE ;
BEGIN
(* Up-date at each second... *)
Inc(compteur);
IF (compteur>=$12) AND NOT ItClk_active THEN
BEGIN
(* No multiple entrance in this area ! *)
ItClk_active := TRUE;
(* 8259 and CPU acquittance to allow the serial receipts... *)
Inline($50/ (* push ax *)
$B0/$20/ (* mov al,20h *)
$E6/$20/ (* out 20h,al *)
$58); (* pop ax *)
Inline($FB); (* sti *)
(* Checking the connect status. *)
HayesModemState;
(* Writting the "C" or "F" alert into screen. *)
IF Show_CorF THEN
BEGIN
IF connected THEN
BEGIN
IF MEM[$40:$49] IN [2,3,7] THEN
MEMW[seg_ecran:158] := $7043
ELSE MEMW[seg_ecran:76] := $7043
END
ELSE
BEGIN
IF MEM[$40:$49] IN [2,3,7] THEN
MEMW[seg_ecran:158] := $7046
ELSE MEMW[seg_ecran:76] := $7046
END;
END;
(* That's the end of our clock interrupt. *)
ItClk_active := FALSE;
compteur := 0
END;
(* Call to the previous clock interrupt *)
Inline($9C/ (* pushf *)
$FF/$1E/OldIntrp1C) (* call far dword ptr ds:OldIntrp1C *)
END;
{$F-}
BEGIN
ModemUsed := Hayes; (* HAYES Modem in use... *)
DTR_Cmde := TRUE; (* We want to use DTR as a Cmde indicator*)
HAYESPrefix := '+++'; (* That's the default HAYES Cmde prefix. *)
PulseDial := TRUE; (* Pulses call in use. *)
connected := FALSE; (* We are supposed not to be connected ! *)
Show_CorF := FALSE; (* No connection flag on screen. *)
ItClk_active := FALSE; (* Clock interrupt is NOT activated yet. *)
IF MEM[$0040:$0049]=7 THEN (* Video RAM segment. *)
seg_ecran := $B000
ELSE seg_ecran := $B800;
WITH reg88 DO
BEGIN (* Stores the previous clock interrupt *)
ax := $351C; (* in use before setting the new one. *)
Intr($21,Dos.Registers(reg88));
OldIntrp1C.Offset := bx;
OldIntrp1C.Segment := es;
END;
NoSound (* Speaker initialization... *)
END.